﻿/*--------------------------------------------------------------------\
|       _____ _                      __  __ _    _  _____ _    _      |
|      / ____| |                    |  \/  | |  | |/ ____| |  | |     |
|     | (___ | |__   __ _ _ __ _ __ | \  / | |  | | (___ | |__| |     |
|      \___ \| '_ \ / _` | '__| '_ \| |\/| | |  | |\___ \|  __  |     |
|      ____) | | | | (_| | |  | |_) | |  | | |__| |____) | |  | |     |
|     |_____/|_| |_|\__,_|_|  | .__/|_|  |_|\____/|_____/|_|  |_|     |
|                             | |                                     |
|                             |_| Copyright(C) Shawn Sagady 2010      |
|=-------------------------------------------------------------------=|
|   Please reference the CREDITS.TXT file for license and credits.    |
\--------------------------------------------------------------------*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharpMUSH
{
    /// <summary>
    /// Flag object used for permission checking on objects.
    /// </summary>
    public class Flag
    {
        public string Name { get; set; }
        public char Letter { get; set; }
        public ObjectType Type { get; set; }
        public Perm Perms { get; set; }
        public Perm NPerms { get; set; }

        /// <summary>
        /// Instantiate a new Flag object
        /// </summary>
        /// <param name="name">Name of Flag</param>
        /// <param name="letter">char representing Flag</param>
        /// <param name="type">Type of objects flag can be applied to</param>
        public Flag(String name, char letter, ObjectType type)
        {
            Name = name;
            Letter = letter;
            Type = type;
            Perms = Perm.ANY;
            NPerms = Perm.ANY;
        }

        /// <summary>
        /// Instantiate a new Flag object
        /// </summary>
        /// <param name="name">Name of Flag</param>
        /// <param name="letter">char representing Flag</param>
        /// <param name="type">Type of objects the flag can be applied to</param>
        /// <param name="perms">Permissions to see / set a flag</param>
        /// <param name="nperms">Permissions to see / remove a flag</param>
        public Flag(String name, char letter, ObjectType type,
            Perm perms, Perm nperms)
        {
            Name = name;
            Letter = letter;
            Type = type;
            Perms = perms;
            NPerms = nperms;
            
        }

        

    }

    [Flags]
    public enum Perm
    {
        NONE        = 0x0,
        ANY         = 0x10,
        INHERIT     = 0x20,
        OWNED       = 0x40,
        ROYAL       = 0x80,
        WIZARD      = 0x100,
        GOD         = 0x200,
        INTERNAL    = 0x400,
        DARK        = 0x800,
        MDARK       = 0x1000,
        ODARK       = 0x2000,
        DISABLED    = 0x4000,
        LOG         = 0x8000
    }

    public static class Flags
    {
        /// <summary>
        /// Master Flag List, this starts empty and must be populated from DB or Default Flag List
        /// </summary>
        static List<Flag> flagList = new List<Flag>();
        
        /// <summary>
        /// Default flag list used for populating a blank DB.
        /// </summary>
        static List<Flag> flagListDefault = new List<Flag>()
        {
            {new Flag("CHOWN_OK", 'C', ObjectType.NONE)},
            {new Flag("DARK", 'D', ObjectType.NONE)},
            {new Flag("GOING", 'G', ObjectType.NONE, Perm.INTERNAL, Perm.INTERNAL)},
            {new Flag("HAVEN", 'H', ObjectType.NONE)},
            {new Flag("TRUST", 'I', ObjectType.NONE, Perm.INHERIT, Perm.INHERIT)},
            {new Flag("LINK_OK", 'L', ObjectType.NONE)},
            {new Flag("OPAQUE", 'O', ObjectType.NONE)},
            {new Flag("QUIET", 'Q', ObjectType.NONE)},
            {new Flag("STICKY", 'S', ObjectType.NONE)},
            {new Flag("UNFINDABLE", 'U', ObjectType.NONE)},
            {new Flag("VISUAL", 'V', ObjectType.NONE, Perm.ANY, Perm.ANY)},
            {new Flag("WIZARD", 'W', ObjectType.NONE, Perm.INHERIT | Perm.WIZARD | Perm.LOG,
                Perm.INHERIT | Perm.WIZARD)},
            {new Flag("SAFE", 'X', ObjectType.NONE)},
            {new Flag("AUDIBLE", 'a', ObjectType.NONE)},
            {new Flag("DEBUG", 'b', ObjectType.NONE)},
            {new Flag("NO_WARN", 'w', ObjectType.NONE)},
            {new Flag("ENTER_OK", 'e', ObjectType.NONE)},
            {new Flag("HALT", 'h', ObjectType.NONE)},
            {new Flag("NO_COMMAND", 'n', ObjectType.NONE)},
            {new Flag("LIGHT", 'l', ObjectType.NONE)},
            {new Flag("ROYALTY", 'r', ObjectType.NONE, Perm.INHERIT | Perm.ROYAL | Perm.LOG,
                Perm.INHERIT | Perm.ROYAL)},
            {new Flag("TRANSPARENT", 't', ObjectType.NONE)},
            {new Flag("VERBOSE", 'v', ObjectType.NONE)},
            {new Flag("ANSI", 'A', ObjectType.PLAYER)},
            {new Flag("COLOR", 'C', ObjectType.PLAYER)},
            {new Flag("MONITOR", 'M', ObjectType.PLAYER | ObjectType.THING | ObjectType.ROOM, Perm.ANY, Perm.ANY)},
            {new Flag("NOSPOOF", '"', ObjectType.PLAYER, Perm.ANY | Perm.ODARK, Perm.ANY | Perm.ODARK)},
            {new Flag("SHARED", 'Z', ObjectType.PLAYER)},
            {new Flag("TRACK_MONEY", '\0', ObjectType.PLAYER)},
            {new Flag("CONNECTED", 'c', ObjectType.PLAYER, Perm.INTERNAL | Perm.MDARK,
                Perm.INTERNAL | Perm.MDARK)},
            {new Flag("GAGGED", 'g', ObjectType.PLAYER, Perm.WIZARD, Perm.WIZARD)},
            {new Flag("MYOPIC", 'm', ObjectType.PLAYER)},
            {new Flag("TERSE", 'x', ObjectType.PLAYER | ObjectType.THING)},
            {new Flag("JURY_OK", 'j', ObjectType.PLAYER, Perm.ROYAL, Perm.ROYAL)},
            {new Flag("JUDGE", 'J', ObjectType.PLAYER, Perm.ROYAL, Perm.ROYAL)},
            {new Flag("FIXED", 'F', ObjectType.PLAYER, Perm.WIZARD, Perm.WIZARD)},
            {new Flag("UNREGISTERED", '?', ObjectType.PLAYER, Perm.ROYAL, Perm.ROYAL)},
            {new Flag("ON-VACATION", 'o', ObjectType.PLAYER)},
            {new Flag("SUSPECT", 's', ObjectType.PLAYER, Perm.WIZARD | Perm.MDARK | Perm.LOG,
                Perm.WIZARD | Perm.MDARK)},
            {new Flag("PARANOID", '\0', ObjectType.PLAYER, Perm.ANY | Perm.ODARK, Perm.ANY | Perm.ODARK)},
            {new Flag("NOACCENTS", '~', ObjectType.PLAYER)},
            {new Flag("DESTROY_OK", 'd', ObjectType.THING)},
            {new Flag("PUPPET", 'p', ObjectType.THING)},
            {new Flag("NO_LEAVE", 'N', ObjectType.THING)},
            {new Flag("LISTEN_PARENT", '^', ObjectType.THING | ObjectType.ROOM)},
            {new Flag("Z_TEL", 'Z', ObjectType.THING | ObjectType.ROOM)},
            {new Flag("ABODE", 'A', ObjectType.ROOM)},
            {new Flag("FLOATING", 'F', ObjectType.ROOM)},
            {new Flag("JUMP_OK", 'J', ObjectType.ROOM)},
            {new Flag("NO_TEL", 'N', ObjectType.ROOM)},
            {new Flag("UNINSPECTED", 'u', ObjectType.ROOM, Perm.ROYAL, Perm.ROYAL)},
            {new Flag("CLOUDY", 'x', ObjectType.EXIT)},
            {new Flag("GOING_TWICE", '\0', ObjectType.NONE, Perm.INTERNAL | Perm.DARK, Perm.INTERNAL | Perm.DARK)},
            {new Flag("KEEPALIVE", 'k', ObjectType.PLAYER)},
            {new Flag("NO_LOG", '\0', ObjectType.NONE, Perm.WIZARD | Perm.MDARK | Perm.LOG, Perm.WIZARD | Perm.MDARK)},
            {new Flag("OPEN_OK", '\0', ObjectType.ROOM)}
        };

        /// <summary>
        /// Find a flag reference
        /// </summary>
        /// <param name="name">Flag Name to search for.</param>
        /// <returns>Flag</returns>
        public static Flag Find(String name)
        {
            return flagList.First(f => f.Name == name);
        }

        /// <summary>
        /// Find a flag reference
        /// </summary>
        /// <param name="letter">Single character Flag token</param>
        /// <returns>Flag</returns>
        public static Flag Find(char letter)
        {
            return flagList.First(f => f.Letter == letter);
        }

        /// <summary>
        /// Load default flags into the main list.
        /// </summary>
        public static void LoadDefault()
        {
            foreach (Flag flag in flagListDefault)
            {
                flagList.Add(flag);
            }
        }

        /// <summary>
        /// Get a reference to the master flag List.
        /// </summary>
        /// <returns></returns>
        public static List<Flag> GetList()
        {
            return flagList;
        }

    }
}
